package com.biz.primus.model.misc.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * @author yanweijin
 * @date 2017/6/1
 */
@Slf4j
public class HttpUtils {

	private static SSLConnectionSocketFactory trustAllSSLConnectionSocketFactory = createTrustAllSSLConnectionSocketFactory();



	public static String executePostRequest(HttpUriRequest req) throws HttpException {
		return executePostRequestInternal(req,0);

	}
	private static String executePostRequestInternal(HttpUriRequest req,int retryCount) throws HttpException {
		try(CloseableHttpClient client = HttpUtils.createSSLClient()) {
			long begin = System.currentTimeMillis();
			CloseableHttpResponse resp = client.execute(req);
			int statusCode = resp.getStatusLine().getStatusCode();
			if(statusCode>=300){
				throw new HttpException("http接口不可用,返回状态:"+statusCode);
			}
			HttpEntity entity = resp.getEntity();
			long end = System.currentTimeMillis();
			log.info("exec http request ms={},uri={}",end-begin,req.getURI());
			return EntityUtils.toString(entity);
		} catch (IOException e) {
			e.printStackTrace();
			if(retryCount < 2){
				log.error("execute http request error, retry count = {}", retryCount, e);
				return executePostRequestInternal(req,++retryCount);
			}else{
				throw new RuntimeException(e);
			}
		}
	}

	public static CloseableHttpClient createSSLClient(){
		return HttpClients.custom().setSSLSocketFactory(trustAllSSLConnectionSocketFactory).build();
	}
	private static SSLConnectionSocketFactory createTrustAllSSLConnectionSocketFactory() {
		try {
			SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(new TrustStrategy() {
				@Override
				public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
					return true;
				}
			}).build();
			return new SSLConnectionSocketFactory(sslContext,new DefaultHostnameVerifier());
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

}
